package com.yazi.mxz.behavior.quartz;

import java.util.List;

import javax.annotation.Resource;

import org.apdplat.word.WordSegmenter;
import org.apdplat.word.dictionary.DictionaryFactory;
import org.apdplat.word.segmentation.Word;
import org.apdplat.word.util.WordConfTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.common.tool.WebContextFactoryUtil;
import com.myframework.smhj.hibernate.Paging;
import com.myframework.smhj.hibernate.Searching;
import com.myframework.smhj.hibernate.Page;
import com.myframework.smhj.hibernate.SearchingFactory;
import com.yazi.mxz.behavior.common.ValueFactory;
import com.yazi.mxz.behavior.entity.beans.StoreGoods;
import com.yazi.mxz.behavior.entity.enums.DataSyncType;
import com.yazi.mxz.behavior.entity.enums.StoreGoodsStatus;
import com.yazi.mxz.behavior.entity.repository.Category;
import com.yazi.mxz.behavior.entity.repository.DataSyncLog;
import com.yazi.mxz.behavior.entity.repository.GoodsClassify;
import com.yazi.mxz.behavior.repository.CategoryRepository;
import com.yazi.mxz.behavior.repository.GoodsClassifyRepository;
import com.yazi.mxz.behavior.repository.StoreGoodsRepository;
import com.yazi.mxz.behavior.repository.StoreRepository;
import com.yazi.mxz.behavior.service.StoreGoodsService;

/**
 * 店铺商品同步(from oracle to mongodb)
 * @author mo_yq5
 * @date 2015-9-8
 */
public class StoreGoodsSyncQuartz extends SyncQuartzAbstract {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	public static boolean reset = false;
	
	@Resource
	StoreGoodsRepository storeGoodsRepository;
	@Resource
	GoodsClassifyRepository goodsClassifyRepository;
	@Resource
	CategoryRepository categoryRepository;
	@Resource
	StoreRepository storeRepository;	
	@Resource
	StoreGoodsService storeGoodsService;
	
	static {
		 WordConfTools.set("dic.path", "classpath:dic.txt, classpath:mydic.txt");
		 DictionaryFactory.reload();
	}
	
	public boolean work() {
		if (isWorking) {
			logger.debug("店铺商品 sync working");
			return false;
		}
		
		if (reset) {
			reset = false;			
			logger.info("店铺商品 del all: {}", storeGoodsRepository.count());
			dataSyncLogRepository.delete(DataSyncType.STORE_GOODS.ordinal());
			storeGoodsRepository.deleteAll();
		}
		
		if (!WebContextFactoryUtil.getApplicationContext().getBean(StoreSyncQuartz.class).work()) {
			logger.debug("店铺商品 sync -> wait store sync");
			return false;
		}
		if (!WebContextFactoryUtil.getApplicationContext().getBean(GoodsClassifySyncQuartz.class).work()) {
			logger.debug("店铺商品 sync -> wait goodsClassify sync");
			return false;
		}
		
		logger.info("店铺商品 sync start：{}", storeGoodsRepository.count());
		
		isWorking = true;
		amount = 0;
		
		sycLog = dataSyncLogRepository.findOne(DataSyncType.STORE_GOODS.ordinal());
		if (null == sycLog) {
			sycLog = new DataSyncLog();
			sycLog.setId(DataSyncType.STORE_GOODS.ordinal());
			sycLog.setLastTime(-1L);
			dataSyncLogRepository.insert(sycLog);
		}
		
		// 最后更新的那条记录的时间作为下次同步的时间依据
		long latestTime = 0;
		
		Searching si = SearchingFactory.createSearching("updateTime", true, 1);
		
		Page<StoreGoods> page;
		
		try {
			
			page = storeGoodsService.listByGtUpdateTime(sycLog.getLastTime(), si);		
			if (page.getPaging().getTotalResult() == 0) {
				latestTime = DateUtil.getTimeStamp();
			} else {
				latestTime = page.getList().get(0).getUpdateTime();
				
				si.setPageSize(Searching.MAX_PAGE_SIZE);
				checkStoreGoods(si);
			}
			
			sycLog.setLastTime(latestTime);
			dataSyncLogRepository.save(sycLog);
			logger.info("店铺商品 sync end: {}", amount);			
			
		} catch (Exception e) {
			logger.error("店铺商品同步异常：", e);
			return false;
		} finally {
			isWorking = false;			
		}
		return true;
	}
	
	private void checkStoreGoods(Searching si) {
		
		Page<StoreGoods> page = storeGoodsService.listByGtUpdateTime(sycLog.getLastTime(), si);
		List<StoreGoods> list = page.getList();
    	for (StoreGoods sg : list) {

    		storeGoodsRepository.delete(sg.getStoreGoodsId());
    		if (sg.getStatus() != StoreGoodsStatus.ON.ordinal()) {
    			// 非上架商品
    			logger.debug("店铺商品 sync -> off: {},{}", sg.getStoreGoodsId(), sg.getName());
    			continue;
    		}
    		
    		// store of mongodb
    		com.yazi.mxz.behavior.entity.repository.Store store0mg = storeRepository.findOne(sg.getStoreId());
    		if (null == store0mg) {
    			// 店铺关闭
    			logger.debug("店铺商品 sync -> store closed: {},{}", sg.getStoreGoodsId(), sg.getName());
    			continue;
    		}
    		
    		logger.info("店铺商品 sync: {},{}", sg.getStoreGoodsId(), sg.getName());
    		
    		amount++;
    		    		
    		// storeGoods for mongodb
    		com.yazi.mxz.behavior.entity.repository.StoreGoods sg4mg = new com.yazi.mxz.behavior.entity.repository.StoreGoods();
    		
    		int promType = 0;
    		if (sg.getAtDiscount()) {// 折
    			promType |= ~(1 << 0);
    		}
    		if (sg.getAtGift()) {// 赠
    			promType |= ~(1 << 1);
    		}    		
    		sg4mg.setPromType(promType);
    		
    		ValueFactory.combine(sg, sg4mg);
    		
    		sg4mg.setStore(store0mg);
    		sg4mg.setLocation(store0mg.getLocation());
    		
    		// keywords
    		StringBuffer keywordsSb = new StringBuffer();
    		List<Word> words =  WordSegmenter.seg(sg4mg.getTitle() + sg4mg.getSubTitle());
    		for (Word word : words) {
    			if (null != word.getText() && word.getText().length() > 1 && !word.getText().equals("null") && !word.getText().matches("^\\d\\S*$")) {
    				keywordsSb.append(word.getText() + " ");
    			}    			
    		}
    		String keywords = keywordsSb.toString();
    		logger.info("keywords: {}", keywords);
    		sg4mg.setKeywords(keywords);
    		
    		// classifyId
    		setClassifyId(sg4mg, goodsClassifyRepository.findOne(sg.getClassifyId()));
    		
    		// catId
    		setCatId(sg4mg, categoryRepository.findOne(sg.getCatId()));
    		
    		storeGoodsRepository.insert(sg4mg);
    		
		}
    	
    	Paging pi = page.getPaging();
    	if (pi.getNowPage() <pi.getTotalPage()) {
    		si.setNowPage(pi.getNowPage() + 1);
    		checkStoreGoods(si);
    	}

	}
	
	/**
	 * 指定每一级自定义类目ID
	 * @param sg4mg 店铺商品
	 * @param gc	目标类目
	 */
	private void setClassifyId(com.yazi.mxz.behavior.entity.repository.StoreGoods sg4mg,  GoodsClassify gc) {
		switch(gc.getDeep()) {
		case 0:
			sg4mg.setClassifyId0(gc.getClassifyId());
			break;
		case 1:
			sg4mg.setClassifyId1(gc.getClassifyId());
			gc = goodsClassifyRepository.findOne(gc.getParentId());
			setClassifyId(sg4mg,  gc);
			break;
		//...
		}		
	}

	/**
	 * 指定每一级系统类目ID
	 * @param sg4mg 店铺商品
	 * @param cat	目标类目
	 */
	private void setCatId(com.yazi.mxz.behavior.entity.repository.StoreGoods sg4mg,  Category cat) {
		switch(cat.getDeep()) {
		case 1:
			sg4mg.setCatId0(cat.getCatId());
			break;
		case 2:
			sg4mg.setCatId1(cat.getCatId());
			cat = categoryRepository.findOne(cat.getParentId());
			setCatId(sg4mg,  cat);
			break;
		case 3:
			sg4mg.setCatId2(cat.getCatId());
			cat = categoryRepository.findOne(cat.getParentId());
			setCatId(sg4mg,  cat);
			break;
		//...
		}		
	}

}
